/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.exporter.excel.imp;

import cn.easyplatform.messages.vos.datalist.ListHeaderVo;
import cn.easyplatform.web.exporter.excel.CellValueSetter;
import org.apache.poi.ss.usermodel.Cell;
import org.zkoss.zk.ui.Component;

import java.text.DecimalFormatSymbols;
import java.util.Locale;

import static cn.easyplatform.web.exporter.util.Utils.getStringValue;


/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class CellValueSetterImpl implements CellValueSetter<Component> {

    private final DateParser _dateParser;
    private final DecimalFormatSymbols dfs;

    public CellValueSetterImpl(Locale locale) {
        _dateParser = new DateParser(locale);
        dfs = new DecimalFormatSymbols(locale);
    }

    @Override
    public void setCellValue(ListHeaderVo listheader, Component component,
                             Cell cell) {
        setCellValue(listheader, getStringValue(component), cell);
    }

    @Override
    public void setCellValue(Component component, Cell cell) {
        setCellValue(null, getStringValue(component), cell);
    }

    private void setCellValue(ListHeaderVo listheader, String value, Cell cell) {
        if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) {
            cell.setCellValue(Boolean.valueOf(value));
        } else if (listheader == null || listheader.getType() == null) {
            parseAndSetCellValueToDoubleDateOrString(value, cell);
        } else {
            switch (listheader.getType()) {
                case CHAR:
                case VARCHAR:
                case CLOB:
                    cell.setCellValue(value);
                    break;
                case LONG:
                case INT:
                case NUMERIC:
                case TIME:
                case DATE:
                case DATETIME:
                    parseAndSetCellValueToDoubleDateOrString(value, cell);
                    break;
                case BOOLEAN:
                    cell.setCellValue(value);
                    break;
                default:
                    parseAndSetCellValueToDoubleDateOrString(value, cell);
            }
        }
    }

    private void parseAndSetCellValueToDoubleDateOrString(String txt, Cell cell) {
        final char dot = dfs.getDecimalSeparator();
        final char comma = dfs.getGroupingSeparator();
        String txt0 = txt;
        if (dot != '.' || comma != ',') {
            final int dotPos = txt.lastIndexOf(dot);
            txt0 = txt.replace(comma, ',');
            if (dotPos >= 0) {
                txt0 = txt0.substring(0, dotPos) + '.'
                        + txt0.substring(dotPos + 1);
            }
        }

        try {
            final Double val = Double.parseDouble(txt0);
            cell.setCellValue(val);
        } catch (NumberFormatException ex) {
            parseAndSetCellValueToDateOrString(txt, cell);
        }
    }

    private void parseAndSetCellValueToDateOrString(String txt, Cell cell) {
        try {
            _dateParser.parseToDate(txt);
            cell.setCellValue(txt);
        } catch (Exception e) {
            cell.setCellValue(txt);
        }
    }
}